R Hypothesis Test

Assume the predetermined significance level is 0.05. 假设预定的显着性水平是0.05。

1 Shapiro-Wilk Test W检验(Shapiro–Wilk (夏皮罗–威克尔 ) W统计量检验)

Null hypothesis: 零假设: The sample came from a normally distributed population. 样本来自正态分布总体

检验数据是否符合正态分布,R函数:shapiro.test().

结果含义:当p值小于某个显著性水平α(比如0.05)时,则认为 样本不是来自正态分布的总体,否则则承认样本来自正态分布的总体。

install.packages("stats")
library(stats)
# args() function displays the argument names and corresponding default values of a function or primitive.
# args()函数显示一个函数的参数名称和相应的默认值。
args(shapiro.test)
#function (x) 
#NULL

# Example 1:
# Test random sample from a normal distribution.
# 测试来自正态分布的随机抽样。
set.seed(1)
x <- rnorm(150)
res <- shapiro.test(x)

res$p.value # > 0.05
[1] 0.7885523
# Conclusion: We are unable to reject the null hypothesis.
# 结论:我们无法拒绝零假设。

# Example 2:
# Test daily observations of S&P 500 from 1981-01 to 1991-04.
# 测试S&P500指数从1981-01到1991-04的日观察值。
install.packages("Ecdat")
library(Ecdat)
data(SP500)
class(SP500)
# [1] "data.frame"
SPreturn = SP500$r500 # use the $ to index a column of the data.frame
# 用$符号取出数据框中的一列
(res <- shapiro.test(SPreturn))
#         Shapiro-Wilk normality test
# data: SPreturn
# W = 0.8413, p-value < 2.2e-16

names(res)
# [1] "statistic" "p.value" "method" "data.name"

res$p.value # < 0.05
# [1] 2.156881e-46
# Conclusion: We should reject the null hypothesis.
# 结论:我们应该拒绝零假设。

2 Jarque-Bera Test

Null hypothesis: The skewness and the excess kurtosis of samples are zero. 样本的偏度和多余峰度均为零

install.packages("tseries")
library(tseries)
args(jarque.bera.test)
# function (x) 
# NULL

# Example 1: 
# Test random sample from a normal distribution
set.seed(1)
x <- rnorm(150)
res <- jarque.bera.test(x)

names(res)
# [1] "statistic" "parameter" "p.value" "method" "data.name"

res$p.value # > 0.05
# X-squared 
# 0.8601533 
# Conclusion: We should not reject the null hypothesis. 

# Example 2:
# Test daily observations of S&P 500 from 1981–01 to 1991–04
install.packages("Ecdat")
library(Ecdat)
data(SP500)
class(SP500)
# [1] "data.frame"
SPreturn = SP500$r500 # use the $ to index a column of the data.frame
(res <- jarque.bera.test(SPreturn))
#         Jarque Bera Test
# data: SPreturn
# X-squared = 648508.6, df = 2, p-value < 2.2e-16

names(res)
# [1] "statistic" "parameter" "p.value" "method" "data.name"

res$p.value # < 0.05
# X-squared 
#         0 
# Conclusion: We should reject the null hypothesis.

3 Correlation Test 相关性检验

R函数:cor.test()

Null hypothesis: The correlation is zero. 样本相关性为0

结果含义:如果p值很小,则拒绝原假设,认为x,y是相关的。否则认为是不相关的。

library(stats)
cor.test(x, y,
  alternative = c("two.sided", "less", "greater"),
  method = c("pearson", "kendall", "spearman"),
  exact = NULL, 
  conf.level = 0.95, ...)

另外一个例子:

install.packages("stats")
library(stats)
args(getS3method("cor.test","default"))
# function (x, y, alternative = c("two.sided", "less", "greater"), 
#     method = c("pearson", "kendall", "spearman"), exact = NULL, 
#     conf.level = 0.95, continuity = FALSE, ...) 
# NULL

# x, y: numeric vectors of the data to be tested
# x, y: 进行测试的数据的数值向量

# alternative: controls two-sided test or one-sided test
# alternative: 控制进行双侧检验或单侧检验

# method: "pearson", "kendall", or "spearman"

# conf.level: confidence level for confidence interval
# conf.level: 置信区间的置信水平


# Example:
# Test the correlation between the food industry and the market portfolio.
# 测试在食品行业的收益和市场投资组合之间的相关性。
data(Capm,package="Ecdat")
(res <- cor.test(Capm$rfood,Capm$rmrf))
#         Pearson's product-moment correlation
# 皮尔逊积矩相关
# data: Capm$rfood and Capm$rmrf
# t = 27.6313, df = 514, p-value < 2.2e-16
# alternative hypothesis: true correlation is not equal to 0
# 备择假设:真正的相关性不等于0
# 95 percent confidence interval:
# 95%置信区间
#  0.7358626 0.8056348
# sample estimates:
# 样本估计
#       cor 
# 0.7730767 

names(res)
# [1] "statistic" "parameter" "p.value" "estimate" 
# [5] "null.value" "alternative" "method" "data.name" 
# [9] "conf.int" 

res$p.value # < 0.05
# [1] 0
# Conclusion: We should reject the null hypothesis.

4 Durbin-Watson Test

Null hypothesis: The autocorrelation of the disturbance is 0. 干扰的自相关为0

install.packages("car")
library(car)
args(durbinWatsonTest) 
# dwt is an abbreviation for durbinWatsonTest
# dwt是durbinWatsonTest的简称。
# function (model, ...) 
# NULL
# model: a linear-model object, or a vector of residuals from a linear model
# model: 一个线性模型对象,或线性模式的残差向量

install.packages("lmtest")
library(lmtest)
args(dwtest)
# function (formula, order.by = NULL, alternative = c("greater", 
#     "two.sided", "less"), iterations = 15, exact = NULL, tol = 1e-10, 
#     data = list()) 
# NULL

# Example:
# Test autocorrelation in residuals of the CAPM model
# CAPM模型的残差自相关测试
fit.lm <- lm(Capm$rfood ~ Capm$rmrf)
(res <- dwt(fit.lm))
 # lag Autocorrelation D-W Statistic p-value
 #   1 0.1163382 1.765306 0.014
 # Alternative hypothesis: rho != 0

names(res)
# [1] "r" "dw" "p" "alternative"

res$p # < 0.05
# [1] 0.014
# Conclusion: We should reject the null hypothesis.

(res <- dwtest(fit.lm))
#         Durbin-Watson test
# data: fit.lm
# DW = 1.7653, p-value = 0.003757
# alternative hypothesis: true autocorrelation is greater than 0
# 备择假设:真正的自相关大于0

names(res)
# [1] "statistic" "method" "alternative" "p.value" 
# [5] "data.name" 

res$p.value # < 0.05
# [1] 0.003756644
# Conclusion: We should reject the null hypothesis.

5 Ljung-Box Test

Null hypothesis: The data are independently distributed, i.e. the autocorrelation coefficients are all zero.

数据是独立分布的,也就是说,它的自相关系数都是零

install.packages("stats")
library(stats)
args(Box.test)
# function (x, lag = 1, type = c("Box-Pierce", "Ljung-Box"), fitdf = 0) 
# NULL

install.packages("FinTS")
library(FinTS)
args(AutocorTest)
# function (x, lag = ceiling(log(length(x))), type = c("Ljung-Box", 
#     "Box-Pierce", "rank"), df = lag) 
# NULL

# Example:
# To test first n-lag autocorrelation coefficients are all zero.
# 测试前n次滞后自相关系数均为零。
(res <- Box.test(residuals(fit.lm),lag=5,type="Ljung-Box"))
        # Box-Ljung test
# data: residuals(fit.lm)
# X-squared = 13.7663, df = 5, p-value = 0.01716

names(res)
# [1] "statistic" "parameter" "p.value" "method" "data.name"

res$p.value # < 0.05
# [1] 0.01716429
# Conclusion: We should reject the null hypothesis.

(res <- AutocorTest(residuals(fit.lm),lag=5,type="Ljung-Box"))
        Box-Ljung test
# data: residuals(fit.lm)
# X-squared = 13.7663, df = 5, p-value = 0.01716

names(res)
# [1] "statistic" "parameter" "p.value" "method" 
# [5] "data.name" "Total.observ"

res$p.value # < 0.05
# [1] 0.01716429
# Conclusion: We should reject the null hypothesis.

6 Lagrange Multiplier Test

Null hypothesis: No ARCH effect. 无ARCH效应


install.packages("FinTS")
library(FinTS)
args(ArchTest)
# function (x, lags = 12, demean = FALSE) 
# NULL

# Example:
# Test the residuals for Autoregressive Conditional Heteroscedasticity (volatility clustering).
# 测试残差的自回归条件异方差(波动集聚性)。

(res <- ArchTest(residuals(fit.lm)))
        # ARCH LM-test; Null hypothesis: no ARCH effects
# data: residuals(fit.lm)
# Chi-squared = 182.0362, df = 12, p-value < 2.2e-16

names(res)
# [1] "statistic" "parameter" "p.value" "method" "data.name"

res$p.value # < 0.05
# Chi-squared 
          # 0 
# Conclusion: We should reject the null hypothesis.

7 Dickey-Fuller Test

Null hypothesis: There is a unit root. 单位根存在

install.packages("urca")
library(urca)
args(ur.df)

# function (y, type = c("none", "drift", "trend"), lags = 1, selectlags = c("Fixed", 
#     "AIC", "BIC")) 
# NULL
# y: time series
# y: 时间序列
# type: "none", "drift", or "trend" for regression model
# type: “无”,“漂移”,或“趋势”回归模型
# lags: number of lags or max number of lags if using selectlags
# lags: 滞后量,或在设置selectlags参数后的最大滞后量
# selectlags: "fixed", or either "AIC" or "BIC" for auto-selection
# selectlags: "fixed", 或者用于自动选择的"AIC"或"BIC"

# Example:
library(FinTS)
data(d.sp9003lev)
sp500.level <- window(d.sp9003lev,start="1995-01-01")
(ht <- ur.df(sp500.level,type="trend",lags=20,selectlags="BIC"))
####################################### 
# Augmented Dickey-Fuller Test Unit Root / Cointegration Test # 
####################################### 
# The value of the test statistic is: -1.4807 1.631 1.8925 
# 检验统计量的值分别为:-1.4807 1.631 1.8925

attributes(ht)$teststat # tau3 = -1.480685
#                tau3 phi2 phi3
# statistic -1.480685 1.631008 1.892498

attributes(ht)$cval # > tau3 5pct = -3.41
#       1pct 5pct 10pct
# tau3 -3.96 -3.41 -3.12
# phi2 6.09 4.68 4.03
# phi3 8.27 6.25 5.34

# Conclusion: We cannot reject the null-hypothesis of a unit root
# (tau3 is less negative than its critical value of -3.41)
# 结论:(tau3没有临界值-3.41显著)

8 Phillips & Ouliaris Test

Null hypothesis: No cointegration. 没有协整关系

install.packages("urca")
library(urca)
args(ca.po)

# function (z, demean = c("none", "constant", "trend"), lag = c("short", 
#     "long"), type = c("Pu", "Pz"), tol = NULL) 
# NULL
# x: matrix or multivariate time series to be tested
# x: 用于测试的矩阵或多维时间序列
# demean: "none", "constant", or "trend"
# lag: "short" or "long" for the length of lags
# lag: 滞后长度,"short"或者"long"
# type: "Pu" or "Pz"

install.packages("tseries")
library(tseries)
args(po.test)
# function (x, demean = TRUE, lshort = TRUE) 
# NULL
# x: matrix or multivariate time series to be tested
# demean: should an intercept be included in the cointegration
# demean: 协整是否包含截距
# regression: (T/F)
# lshort: T = short number of lags, F = long number of lags
# lshort: T = 短滞后阶数, F = 长滞后阶数

# Example:
data(ecb) # Macroeconomic data of the Euro Zone
# 欧元区宏观经济数据
m3.real <- ecb[,"m3"]/ecb[,"gdp.defl"]
gdp.real <- ecb[,"gdp.nom"]/ecb[,"gdp.defl"]
rl <- ecb[,"rl"]
ecb.data <- cbind(m3.real, gdp.real, rl)

(m3d.po <- ca.po(ecb.data, type="Pz"))
################################# 
# Phillips and Ouliaris Unit Root / Cointegration Test # 
################################# 
# The value of the test statistic is: 18.4658 
slotNames(m3d.po)
# [1] "z" "type" "model" "lag" "cval" 
# [6] "res" "teststat" "testreg" "test.name"
m3d.po@teststat
# [1] 18.46584
m3d.po@cval
#                   10pct 5pct 1pct
# critical values 62.1436 71.2751 89.6679
# Conclusion: We should not reject the null hypothesis.
# (not as extreme as its critical value)
# (不如临界值显著)

(m3d.po <- po.test(ecb.data))
#         Phillips-Ouliaris Cointegration Test
# data: ecb.data
# Phillips-Ouliaris demeaned = -4.4665, Truncation lag
# parameter = 0, p-value = 0.15

names(m3d.po)
# [1] "statistic" "parameter" "p.value" "method" "data.name"

m3d.po$p.value
# [1] 0.15
# Conclusion: We should not reject the null hypothesis.

9 Johansen Procedure Test

Null hypothesis: There are n cointegrated vectors. 有n个协整向量

install.packages("urca")
library(urca)
args(ca.jo)
# function (x, type = c("eigen", "trace"), ecdet = c("none", "const", 
#     "trend"), K = 2, spec = c("longrun", "transitory"), season = NULL, 
#     dumvar = NULL) 
# NULL
# x: data matrix to be investigated for cointegration
# x: 用于检查协整的数据矩阵
# type: "eigen" or "trace"
# ecdet: "none", "const", or "trend"
# K: number of lags
# K: 滞后阶数
# spec: VECM specification, "longrun" or "transitory"
# spec: VECM规范:"longrun"或"transitory"

# Example:
data(denmark)
sjd <- denmark[, c("LRM", "LRY", "IBO", "IDE")]
(sjd.vecm <- ca.jo(sjd, ecdet = "const", type="eigen", K=2,
+ spec="longrun",season=4))

################################# 
# Johansen-Procedure Unit Root / Cointegration Test # 
################################# 
# The value of the test statistic is: 2.3522 6.3427 10.362 30.0875 
summary(sjd.vecm)
###################### 
# Johansen-Procedure # 
###################### 
# Test type: maximal eigenvalue statistic (lambda max) , without linear trend and constant in cointegration 
# 测试类型:没有线性趋势并协整恒定的最大特征值统计(λ最大)
# Eigenvalues (lambda):
# 特征值(λ):
# [1] 4.331654e-01 1.775836e-01 1.127905e-01 4.341130e-02
# [5] -8.947236e-16
# Values of teststatistic and critical values of test:
# 测试检验统计量的值和临界值:
#           test 10pct 5pct 1pct
# r <= 3 | 2.35 7.52 9.24 12.97
# r <= 2 | 6.34 13.75 15.67 20.20
# r <= 1 | 10.36 19.77 22.00 26.81
# r = 0 | 30.09 25.56 28.14 33.24
# Eigenvectors, normalised to first column:
# 归一化的特征向量
# (These are the cointegration relations)
# 没有协整关系
#             LRM.l2 LRY.l2 IBO.l2 IDE.l2 constant
# LRM.l2 1.000000 1.0000000 1.0000000 1.000000 1.0000000
# LRY.l2 -1.032949 -1.3681031 -3.2266580 -1.883625 -0.6336946
# IBO.l2 5.206919 0.2429825 0.5382847 24.399487 1.6965828
# IDE.l2 -4.215879 6.8411103 -5.6473903 -14.298037 -1.8951589
# constant -6.059932 -4.2708474 7.8963696 -2.263224 -8.0330127
# Weights W:
# (This is the loading matrix)
# (这是载荷矩阵)
#            LRM.l2 LRY.l2 IBO.l2 IDE.l2
# LRM.d -0.21295494 -0.00481498 0.035011128 2.028908e-03
# LRY.d 0.11502204 0.01975028 0.049938460 1.108654e-03
# IBO.d 0.02317724 -0.01059605 0.003480357 -1.573742e-03
# IDE.d 0.02941109 -0.03022917 -0.002811506 -4.767627e-05
#            constant
# LRM.d -4.183363e-13
# LRY.d 4.618135e-13
# IBO.d 3.673136e-14
# IDE.d -1.115087e-14

slotNames(sjd.vecm)
#  [1] "x" "Z0" "Z1" "ZK" "type" 
#  [6] "model" "ecdet" "lag" "P" "season" 
# [11] "dumvar" "cval" "teststat" "lambda" "Vorg" 
# [16] "V" "W" "PI" "DELTA" "GAMMA" 
# [21] "R0" "RK" "bp" "spec" "call" 
# [26] "test.name"
sjd.vecm@teststat
# [1] 2.352233 6.342730 10.361950 30.087451
sjd.vecm@cval # 10.36 < r<=1 = 22.00 
#          10pct 5pct 1pct
# r <= 3 | 7.52 9.24 12.97
# r <= 2 | 13.75 15.67 20.20
# r <= 1 | 19.77 22.00 26.81
# r = 0 | 25.56 28.14 33.24
# Conclusion: There are 1 cointegrated vector.
# 结论:有1个协整向量。

10 K检验(经验分布的Kolmogorov-Smirnov检验)

R函数:ks.test()

如果P值很小,说明拒绝原假设,表明数据不符合F(n,m)分布。

11 T-test T检验

用于正态总体均值假设检验,单样本,双样本都可以。可以双边检验,也可以单边检验。

对于单样本,与给定的均值做比较: (1)双边检验,也就是 Null hypothesis: 这个样本的均值与给定均值相等:H0: u = u0

Alternative hypothesis: 这个样本的均值与给定均值不相等:H1: u ≠ u0

(2)单边检验,也就是 单边检验I Null hypothesis: 这个样本的均值小于给定均值:H0: u ≤ u0

Alternative hypothesis: 这个样本的均值大于给定均值:H1: u > u0

单边检验II(单边检验I反过来) Null hypothesis: 这个样本的均值大于等于给定均值:H0: u ≥ u0

Alternative hypothesis: 这个样本的均值小于给定均值:H1: u < u0

对于双样本,就是两个样本的均值做比较。单边、双边检验与单样本一样。

结果意义:P值小于显著性水平时拒绝原假设,否则,接受原假设。具体的假设要看所选择的是双边假设还是单边假设(又分小于和大于)

t.test(x, y = NULL,
alternative = c("two.sided", "less", "greater"),
mu = 0, paired = FALSE, var.equal = FALSE,
conf.level = 0.95, ...)

12 正态总体方差检验

用于正态总体方差假设检验,单样本,双样本都可以。可以双边检验,也可以单边检验。与均值假设检验类似,不过检验的对象变成方差了。

结果含义:P值小于显著性水平时拒绝原假设,否则,接受原假设。具体的假设要看所选择的是双边假设还是单边假设(又分小于和大于)

t.test(x, y = NULL,
alternative = c("two.sided", "less", "greater"),
mu = 0, paired = FALSE, var.equal = FALSE,
conf.level = 0.95, ...)

13 二项分布总体假设检验

binom.test(x, n, p = 0.5,
alternative = c("two.sided", "less", "greater"),
conf.level = 0.95)

14 Pearson 拟合优度χ2检验

原假设H0:X符合F分布。 p-值小于某个显著性水平,则表示拒绝原假设,否则接受原假设。

chisq.test(x, y = NULL, correct = TRUE,
p = rep(1/length(x), length(x)), rescale.p = FALSE,
simulate.p.value = FALSE, B = 2000)

15 Fisher精确的独立检验:

原假设:X,Y相关

fisher.test(x, y = NULL, workspace = 200000, hybrid = FALSE,
control = list(), or = 1, alternative = "two.sided",
conf.int = TRUE, conf.level = 0.95)

16 McNemar检验:

原假设:两组数据的频数没有区别。

mcnemar.test(x, y = NULL, correct = TRUE)

17 秩相关检验

原假设:x,y相关.

cor.test(x, y,
alternative = c("two.sided", "less", "greater"),
method = "spearman", conf.level = 0.95, ...)

18 Wilcoxon秩检验

原假设:中位数大于,小于,不等于mu.

wilcox.test(x, y = NULL,
alternative = c("two.sided", "less", "greater"),
mu = 0, paired = FALSE, exact = NULL, correct = TRUE,
conf.int = FALSE, conf.level = 0.95, ...)
LS0tDQp0aXRsZTogIlIgSHlwb3RoZXNpcyBUZXN0IE5vdGVib29rIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyBSIEh5cG90aGVzaXMgVGVzdA0KDQpBc3N1bWUgdGhlIHByZWRldGVybWluZWQgc2lnbmlmaWNhbmNlIGxldmVsIGlzIDAuMDUuDQrlgYforr7pooTlrprnmoTmmL7nnYDmgKfmsLTlubPmmK8wLjA144CCDQoNCiMjIDEgU2hhcGlyby1XaWxrIFRlc3QgV+ajgOmqjO+8iFNoYXBpcm/igJNXaWxrICjlpI/nmq7nvZfigJPlqIHlhYvlsJQgKSBX57uf6K6h6YeP5qOA6aqMKQ0KDQpOdWxsIGh5cG90aGVzaXM6DQrpm7blgYforr46DQpUaGUgc2FtcGxlIGNhbWUgZnJvbSBhIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHBvcHVsYXRpb24uDQrmoLfmnKzmnaXoh6rmraPmgIHliIbluIPmgLvkvZMNCg0K5qOA6aqM5pWw5o2u5piv5ZCm56ym5ZCI5q2j5oCB5YiG5biD77yMUuWHveaVsO+8mnNoYXBpcm8udGVzdCgpLg0KDQrnu5PmnpzlkKvkuYnvvJrlvZNw5YC85bCP5LqO5p+Q5Liq5pi+6JGX5oCn5rC05bmzzrEo5q+U5aaCMC4wNSnml7bvvIzliJnorqTkuLoNCuagt+acrOS4jeaYr+adpeiHquato+aAgeWIhuW4g+eahOaAu+S9k++8jOWQpuWImeWImeaJv+iupOagt+acrOadpeiHquato+aAgeWIhuW4g+eahOaAu+S9k+OAgg0KDQpgYGB7ciBSIEh5cG90aGVzaXMgVGVzdH0NCmluc3RhbGwucGFja2FnZXMoInN0YXRzIikNCmxpYnJhcnkoc3RhdHMpDQojIGFyZ3MoKSBmdW5jdGlvbiBkaXNwbGF5cyB0aGUgYXJndW1lbnQgbmFtZXMgYW5kIGNvcnJlc3BvbmRpbmcgZGVmYXVsdCB2YWx1ZXMgb2YgYSBmdW5jdGlvbiBvciBwcmltaXRpdmUuDQojIGFyZ3MoKeWHveaVsOaYvuekuuS4gOS4quWHveaVsOeahOWPguaVsOWQjeensOWSjOebuOW6lOeahOm7mOiupOWAvOOAgg0KYXJncyhzaGFwaXJvLnRlc3QpDQojZnVuY3Rpb24gKHgpIA0KI05VTEwNCg0KIyBFeGFtcGxlIDE6DQojIFRlc3QgcmFuZG9tIHNhbXBsZSBmcm9tIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCiMg5rWL6K+V5p2l6Ieq5q2j5oCB5YiG5biD55qE6ZqP5py65oq95qC344CCDQpzZXQuc2VlZCgxKQ0KeCA8LSBybm9ybSgxNTApDQpyZXMgPC0gc2hhcGlyby50ZXN0KHgpDQoNCnJlcyRwLnZhbHVlICMgPiAwLjA1DQpbMV0gMC43ODg1NTIzDQojIENvbmNsdXNpb246IFdlIGFyZSB1bmFibGUgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuDQojIOe7k+iuuu+8muaIkeS7rOaXoOazleaLkue7nembtuWBh+iuvuOAgg0KDQojIEV4YW1wbGUgMjoNCiMgVGVzdCBkYWlseSBvYnNlcnZhdGlvbnMgb2YgUyZQIDUwMCBmcm9tIDE5ODEtMDEgdG8gMTk5MS0wNC4NCiMg5rWL6K+VU++8hlA1MDDmjIfmlbDku44xOTgxLTAx5YiwMTk5MS0wNOeahOaXpeinguWvn+WAvOOAgg0KaW5zdGFsbC5wYWNrYWdlcygiRWNkYXQiKQ0KbGlicmFyeShFY2RhdCkNCmRhdGEoU1A1MDApDQpjbGFzcyhTUDUwMCkNCiMgWzFdICJkYXRhLmZyYW1lIg0KU1ByZXR1cm4gPSBTUDUwMCRyNTAwICMgdXNlIHRoZSAkIHRvIGluZGV4IGEgY29sdW1uIG9mIHRoZSBkYXRhLmZyYW1lDQojIOeUqCTnrKblj7flj5blh7rmlbDmja7moYbkuK3nmoTkuIDliJcNCihyZXMgPC0gc2hhcGlyby50ZXN0KFNQcmV0dXJuKSkNCiMgICAgICAgICBTaGFwaXJvLVdpbGsgbm9ybWFsaXR5IHRlc3QNCiMgZGF0YTogU1ByZXR1cm4NCiMgVyA9IDAuODQxMywgcC12YWx1ZSA8IDIuMmUtMTYNCg0KbmFtZXMocmVzKQ0KIyBbMV0gInN0YXRpc3RpYyIgInAudmFsdWUiICJtZXRob2QiICJkYXRhLm5hbWUiDQoNCnJlcyRwLnZhbHVlICMgPCAwLjA1DQojIFsxXSAyLjE1Njg4MWUtNDYNCiMgQ29uY2x1c2lvbjogV2Ugc2hvdWxkIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLg0KIyDnu5PorrrvvJrmiJHku6zlupTor6Xmi5Lnu53pm7blgYforr7jgIINCmBgYA0KDQoNCiMjIDIgSmFycXVlLUJlcmEgVGVzdA0KDQpOdWxsIGh5cG90aGVzaXM6DQpUaGUgc2tld25lc3MgYW5kIHRoZSBleGNlc3Mga3VydG9zaXMgb2Ygc2FtcGxlcyBhcmUgemVyby4NCuagt+acrOeahOWBj+W6puWSjOWkmuS9meWzsOW6puWdh+S4uumbtg0KDQpgYGB7ciBKYXJxdWUtQmVyYSBUZXN0fQ0KaW5zdGFsbC5wYWNrYWdlcygidHNlcmllcyIpDQpsaWJyYXJ5KHRzZXJpZXMpDQphcmdzKGphcnF1ZS5iZXJhLnRlc3QpDQojIGZ1bmN0aW9uICh4KSANCiMgTlVMTA0KDQojIEV4YW1wbGUgMTogDQojIFRlc3QgcmFuZG9tIHNhbXBsZSBmcm9tIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbg0Kc2V0LnNlZWQoMSkNCnggPC0gcm5vcm0oMTUwKQ0KcmVzIDwtIGphcnF1ZS5iZXJhLnRlc3QoeCkNCg0KbmFtZXMocmVzKQ0KIyBbMV0gInN0YXRpc3RpYyIgInBhcmFtZXRlciIgInAudmFsdWUiICJtZXRob2QiICJkYXRhLm5hbWUiDQoNCnJlcyRwLnZhbHVlICMgPiAwLjA1DQojIFgtc3F1YXJlZCANCiMgMC44NjAxNTMzIA0KIyBDb25jbHVzaW9uOiBXZSBzaG91bGQgbm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLiANCg0KIyBFeGFtcGxlIDI6DQojIFRlc3QgZGFpbHkgb2JzZXJ2YXRpb25zIG9mIFMmUCA1MDAgZnJvbSAxOTgx4oCTMDEgdG8gMTk5MeKAkzA0DQppbnN0YWxsLnBhY2thZ2VzKCJFY2RhdCIpDQpsaWJyYXJ5KEVjZGF0KQ0KZGF0YShTUDUwMCkNCmNsYXNzKFNQNTAwKQ0KIyBbMV0gImRhdGEuZnJhbWUiDQpTUHJldHVybiA9IFNQNTAwJHI1MDAgIyB1c2UgdGhlICQgdG8gaW5kZXggYSBjb2x1bW4gb2YgdGhlIGRhdGEuZnJhbWUNCihyZXMgPC0gamFycXVlLmJlcmEudGVzdChTUHJldHVybikpDQojICAgICAgICAgSmFycXVlIEJlcmEgVGVzdA0KIyBkYXRhOiBTUHJldHVybg0KIyBYLXNxdWFyZWQgPSA2NDg1MDguNiwgZGYgPSAyLCBwLXZhbHVlIDwgMi4yZS0xNg0KDQpuYW1lcyhyZXMpDQojIFsxXSAic3RhdGlzdGljIiAicGFyYW1ldGVyIiAicC52YWx1ZSIgIm1ldGhvZCIgImRhdGEubmFtZSINCg0KcmVzJHAudmFsdWUgIyA8IDAuMDUNCiMgWC1zcXVhcmVkIA0KIyAgICAgICAgIDAgDQojIENvbmNsdXNpb246IFdlIHNob3VsZCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4NCmBgYA0KDQoNCiMjIDMgQ29ycmVsYXRpb24gVGVzdCDnm7jlhbPmgKfmo4DpqowNCg0KUuWHveaVsO+8mmNvci50ZXN0KCkNCg0KTnVsbCBoeXBvdGhlc2lzOg0KVGhlIGNvcnJlbGF0aW9uIGlzIHplcm8uDQrmoLfmnKznm7jlhbPmgKfkuLowDQoNCue7k+aenOWQq+S5ie+8muWmguaenHDlgLzlvojlsI/vvIzliJnmi5Lnu53ljp/lgYforr7vvIzorqTkuLp4LHnmmK/nm7jlhbPnmoTjgILlkKbliJnorqTkuLrmmK/kuI3nm7jlhbPnmoTjgIINCg0KYGBge3J9DQpsaWJyYXJ5KHN0YXRzKQ0KY29yLnRlc3QoeCwgeSwNCiAgYWx0ZXJuYXRpdmUgPSBjKCJ0d28uc2lkZWQiLCAibGVzcyIsICJncmVhdGVyIiksDQogIG1ldGhvZCA9IGMoInBlYXJzb24iLCAia2VuZGFsbCIsICJzcGVhcm1hbiIpLA0KICBleGFjdCA9IE5VTEwsIA0KICBjb25mLmxldmVsID0gMC45NSwgLi4uKQ0KYGBgDQoNCuWPpuWkluS4gOS4quS+i+WtkO+8mg0KDQpgYGB7ciB9DQppbnN0YWxsLnBhY2thZ2VzKCJzdGF0cyIpDQpsaWJyYXJ5KHN0YXRzKQ0KYXJncyhnZXRTM21ldGhvZCgiY29yLnRlc3QiLCJkZWZhdWx0IikpDQojIGZ1bmN0aW9uICh4LCB5LCBhbHRlcm5hdGl2ZSA9IGMoInR3by5zaWRlZCIsICJsZXNzIiwgImdyZWF0ZXIiKSwgDQojICAgICBtZXRob2QgPSBjKCJwZWFyc29uIiwgImtlbmRhbGwiLCAic3BlYXJtYW4iKSwgZXhhY3QgPSBOVUxMLCANCiMgICAgIGNvbmYubGV2ZWwgPSAwLjk1LCBjb250aW51aXR5ID0gRkFMU0UsIC4uLikgDQojIE5VTEwNCg0KIyB4LCB5OiBudW1lcmljIHZlY3RvcnMgb2YgdGhlIGRhdGEgdG8gYmUgdGVzdGVkDQojIHgsIHk6IOi/m+ihjOa1i+ivleeahOaVsOaNrueahOaVsOWAvOWQkemHjw0KDQojIGFsdGVybmF0aXZlOiBjb250cm9scyB0d28tc2lkZWQgdGVzdCBvciBvbmUtc2lkZWQgdGVzdA0KIyBhbHRlcm5hdGl2ZTog5o6n5Yi26L+b6KGM5Y+M5L6n5qOA6aqM5oiW5Y2V5L6n5qOA6aqMDQoNCiMgbWV0aG9kOiAicGVhcnNvbiIsICJrZW5kYWxsIiwgb3IgInNwZWFybWFuIg0KDQojIGNvbmYubGV2ZWw6IGNvbmZpZGVuY2UgbGV2ZWwgZm9yIGNvbmZpZGVuY2UgaW50ZXJ2YWwNCiMgY29uZi5sZXZlbDog572u5L+h5Yy66Ze055qE572u5L+h5rC05bmzDQoNCg0KIyBFeGFtcGxlOg0KIyBUZXN0IHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBmb29kIGluZHVzdHJ5IGFuZCB0aGUgbWFya2V0IHBvcnRmb2xpby4NCiMg5rWL6K+V5Zyo6aOf5ZOB6KGM5Lia55qE5pS255uK5ZKM5biC5Zy65oqV6LWE57uE5ZCI5LmL6Ze055qE55u45YWz5oCn44CCDQpkYXRhKENhcG0scGFja2FnZT0iRWNkYXQiKQ0KKHJlcyA8LSBjb3IudGVzdChDYXBtJHJmb29kLENhcG0kcm1yZikpDQojICAgICAgICAgUGVhcnNvbidzIHByb2R1Y3QtbW9tZW50IGNvcnJlbGF0aW9uDQojIOearuWwlOmAiuenr+efqeebuOWFsw0KIyBkYXRhOiBDYXBtJHJmb29kIGFuZCBDYXBtJHJtcmYNCiMgdCA9IDI3LjYzMTMsIGRmID0gNTE0LCBwLXZhbHVlIDwgMi4yZS0xNg0KIyBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzOiB0cnVlIGNvcnJlbGF0aW9uIGlzIG5vdCBlcXVhbCB0byAwDQojIOWkh+aLqeWBh+iuvu+8muecn+ato+eahOebuOWFs+aAp+S4jeetieS6jjANCiMgOTUgcGVyY2VudCBjb25maWRlbmNlIGludGVydmFsOg0KIyA5NSXnva7kv6HljLrpl7QNCiMgIDAuNzM1ODYyNiAwLjgwNTYzNDgNCiMgc2FtcGxlIGVzdGltYXRlczoNCiMg5qC35pys5Lyw6K6hDQojICAgICAgIGNvciANCiMgMC43NzMwNzY3IA0KDQpuYW1lcyhyZXMpDQojIFsxXSAic3RhdGlzdGljIiAicGFyYW1ldGVyIiAicC52YWx1ZSIgImVzdGltYXRlIiANCiMgWzVdICJudWxsLnZhbHVlIiAiYWx0ZXJuYXRpdmUiICJtZXRob2QiICJkYXRhLm5hbWUiIA0KIyBbOV0gImNvbmYuaW50IiANCg0KcmVzJHAudmFsdWUgIyA8IDAuMDUNCiMgWzFdIDANCiMgQ29uY2x1c2lvbjogV2Ugc2hvdWxkIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLg0KDQpgYGANCg0KIyMgNCBEdXJiaW4tV2F0c29uIFRlc3QNCg0KTnVsbCBoeXBvdGhlc2lzOg0KVGhlIGF1dG9jb3JyZWxhdGlvbiBvZiB0aGUgZGlzdHVyYmFuY2UgaXMgMC4NCuW5suaJsOeahOiHquebuOWFs+S4ujANCg0KYGBge3IgRHVyYmluLVdhdHNvbiBUZXN0fQ0KaW5zdGFsbC5wYWNrYWdlcygiY2FyIikNCmxpYnJhcnkoY2FyKQ0KYXJncyhkdXJiaW5XYXRzb25UZXN0KSANCiMgZHd0IGlzIGFuIGFiYnJldmlhdGlvbiBmb3IgZHVyYmluV2F0c29uVGVzdA0KIyBkd3TmmK9kdXJiaW5XYXRzb25UZXN055qE566A56ew44CCDQojIGZ1bmN0aW9uIChtb2RlbCwgLi4uKSANCiMgTlVMTA0KIyBtb2RlbDogYSBsaW5lYXItbW9kZWwgb2JqZWN0LCBvciBhIHZlY3RvciBvZiByZXNpZHVhbHMgZnJvbSBhIGxpbmVhciBtb2RlbA0KIyBtb2RlbDog5LiA5Liq57q/5oCn5qih5Z6L5a+56LGh77yM5oiW57q/5oCn5qih5byP55qE5q6L5beu5ZCR6YePDQoNCmluc3RhbGwucGFja2FnZXMoImxtdGVzdCIpDQpsaWJyYXJ5KGxtdGVzdCkNCmFyZ3MoZHd0ZXN0KQ0KIyBmdW5jdGlvbiAoZm9ybXVsYSwgb3JkZXIuYnkgPSBOVUxMLCBhbHRlcm5hdGl2ZSA9IGMoImdyZWF0ZXIiLCANCiMgICAgICJ0d28uc2lkZWQiLCAibGVzcyIpLCBpdGVyYXRpb25zID0gMTUsIGV4YWN0ID0gTlVMTCwgdG9sID0gMWUtMTAsIA0KIyAgICAgZGF0YSA9IGxpc3QoKSkgDQojIE5VTEwNCg0KIyBFeGFtcGxlOg0KIyBUZXN0IGF1dG9jb3JyZWxhdGlvbiBpbiByZXNpZHVhbHMgb2YgdGhlIENBUE0gbW9kZWwNCiMgQ0FQTeaooeWei+eahOaui+W3ruiHquebuOWFs+a1i+ivlQ0KZml0LmxtIDwtIGxtKENhcG0kcmZvb2QgfiBDYXBtJHJtcmYpDQoocmVzIDwtIGR3dChmaXQubG0pKQ0KICMgbGFnIEF1dG9jb3JyZWxhdGlvbiBELVcgU3RhdGlzdGljIHAtdmFsdWUNCiAjICAgMSAwLjExNjMzODIgMS43NjUzMDYgMC4wMTQNCiAjIEFsdGVybmF0aXZlIGh5cG90aGVzaXM6IHJobyAhPSAwDQoNCm5hbWVzKHJlcykNCiMgWzFdICJyIiAiZHciICJwIiAiYWx0ZXJuYXRpdmUiDQoNCnJlcyRwICMgPCAwLjA1DQojIFsxXSAwLjAxNA0KIyBDb25jbHVzaW9uOiBXZSBzaG91bGQgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuDQoNCihyZXMgPC0gZHd0ZXN0KGZpdC5sbSkpDQojICAgICAgICAgRHVyYmluLVdhdHNvbiB0ZXN0DQojIGRhdGE6IGZpdC5sbQ0KIyBEVyA9IDEuNzY1MywgcC12YWx1ZSA9IDAuMDAzNzU3DQojIGFsdGVybmF0aXZlIGh5cG90aGVzaXM6IHRydWUgYXV0b2NvcnJlbGF0aW9uIGlzIGdyZWF0ZXIgdGhhbiAwDQojIOWkh+aLqeWBh+iuvu+8muecn+ato+eahOiHquebuOWFs+Wkp+S6jjANCg0KbmFtZXMocmVzKQ0KIyBbMV0gInN0YXRpc3RpYyIgIm1ldGhvZCIgImFsdGVybmF0aXZlIiAicC52YWx1ZSIgDQojIFs1XSAiZGF0YS5uYW1lIiANCg0KcmVzJHAudmFsdWUgIyA8IDAuMDUNCiMgWzFdIDAuMDAzNzU2NjQ0DQojIENvbmNsdXNpb246IFdlIHNob3VsZCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4NCmBgYA0KDQoNCiMjIDUgTGp1bmctQm94IFRlc3QNCg0KTnVsbCBoeXBvdGhlc2lzOg0KVGhlIGRhdGEgYXJlIGluZGVwZW5kZW50bHkgZGlzdHJpYnV0ZWQsIGkuZS4gdGhlIGF1dG9jb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgYXJlIGFsbCB6ZXJvLg0KDQrmlbDmja7mmK/ni6znq4vliIbluIPnmoTvvIzkuZ/lsLHmmK/or7TvvIzlroPnmoToh6rnm7jlhbPns7vmlbDpg73mmK/pm7YNCg0KYGBge3IgTGp1bmctQm94IFRlc3R9DQppbnN0YWxsLnBhY2thZ2VzKCJzdGF0cyIpDQpsaWJyYXJ5KHN0YXRzKQ0KYXJncyhCb3gudGVzdCkNCiMgZnVuY3Rpb24gKHgsIGxhZyA9IDEsIHR5cGUgPSBjKCJCb3gtUGllcmNlIiwgIkxqdW5nLUJveCIpLCBmaXRkZiA9IDApIA0KIyBOVUxMDQoNCmluc3RhbGwucGFja2FnZXMoIkZpblRTIikNCmxpYnJhcnkoRmluVFMpDQphcmdzKEF1dG9jb3JUZXN0KQ0KIyBmdW5jdGlvbiAoeCwgbGFnID0gY2VpbGluZyhsb2cobGVuZ3RoKHgpKSksIHR5cGUgPSBjKCJManVuZy1Cb3giLCANCiMgICAgICJCb3gtUGllcmNlIiwgInJhbmsiKSwgZGYgPSBsYWcpIA0KIyBOVUxMDQoNCiMgRXhhbXBsZToNCiMgVG8gdGVzdCBmaXJzdCBuLWxhZyBhdXRvY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGFyZSBhbGwgemVyby4NCiMg5rWL6K+V5YmNbuasoea7nuWQjuiHquebuOWFs+ezu+aVsOWdh+S4uumbtuOAgg0KKHJlcyA8LSBCb3gudGVzdChyZXNpZHVhbHMoZml0LmxtKSxsYWc9NSx0eXBlPSJManVuZy1Cb3giKSkNCiAgICAgICAgIyBCb3gtTGp1bmcgdGVzdA0KIyBkYXRhOiByZXNpZHVhbHMoZml0LmxtKQ0KIyBYLXNxdWFyZWQgPSAxMy43NjYzLCBkZiA9IDUsIHAtdmFsdWUgPSAwLjAxNzE2DQoNCm5hbWVzKHJlcykNCiMgWzFdICJzdGF0aXN0aWMiICJwYXJhbWV0ZXIiICJwLnZhbHVlIiAibWV0aG9kIiAiZGF0YS5uYW1lIg0KDQpyZXMkcC52YWx1ZSAjIDwgMC4wNQ0KIyBbMV0gMC4wMTcxNjQyOQ0KIyBDb25jbHVzaW9uOiBXZSBzaG91bGQgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuDQoNCihyZXMgPC0gQXV0b2NvclRlc3QocmVzaWR1YWxzKGZpdC5sbSksbGFnPTUsdHlwZT0iTGp1bmctQm94IikpDQogICAgICAgIEJveC1ManVuZyB0ZXN0DQojIGRhdGE6IHJlc2lkdWFscyhmaXQubG0pDQojIFgtc3F1YXJlZCA9IDEzLjc2NjMsIGRmID0gNSwgcC12YWx1ZSA9IDAuMDE3MTYNCg0KbmFtZXMocmVzKQ0KIyBbMV0gInN0YXRpc3RpYyIgInBhcmFtZXRlciIgInAudmFsdWUiICJtZXRob2QiIA0KIyBbNV0gImRhdGEubmFtZSIgIlRvdGFsLm9ic2VydiINCg0KcmVzJHAudmFsdWUgIyA8IDAuMDUNCiMgWzFdIDAuMDE3MTY0MjkNCiMgQ29uY2x1c2lvbjogV2Ugc2hvdWxkIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLg0KYGBgDQoNCg0KIyMgNiBMYWdyYW5nZSBNdWx0aXBsaWVyIFRlc3QNCg0KTnVsbCBoeXBvdGhlc2lzOg0KTm8gQVJDSCBlZmZlY3QuDQrml6BBUkNI5pWI5bqUDQoNCmBgYHtyIExhZ3JhbmdlIE11bHRpcGxpZXIgVGVzdH0NCg0KaW5zdGFsbC5wYWNrYWdlcygiRmluVFMiKQ0KbGlicmFyeShGaW5UUykNCmFyZ3MoQXJjaFRlc3QpDQojIGZ1bmN0aW9uICh4LCBsYWdzID0gMTIsIGRlbWVhbiA9IEZBTFNFKSANCiMgTlVMTA0KDQojIEV4YW1wbGU6DQojIFRlc3QgdGhlIHJlc2lkdWFscyBmb3IgQXV0b3JlZ3Jlc3NpdmUgQ29uZGl0aW9uYWwgSGV0ZXJvc2NlZGFzdGljaXR5ICh2b2xhdGlsaXR5IGNsdXN0ZXJpbmcpLg0KIyDmtYvor5Xmrovlt67nmoToh6rlm57lvZLmnaHku7blvILmlrnlt67vvIjms6Lliqjpm4bogZrmgKfvvInjgIINCg0KKHJlcyA8LSBBcmNoVGVzdChyZXNpZHVhbHMoZml0LmxtKSkpDQogICAgICAgICMgQVJDSCBMTS10ZXN0OyBOdWxsIGh5cG90aGVzaXM6IG5vIEFSQ0ggZWZmZWN0cw0KIyBkYXRhOiByZXNpZHVhbHMoZml0LmxtKQ0KIyBDaGktc3F1YXJlZCA9IDE4Mi4wMzYyLCBkZiA9IDEyLCBwLXZhbHVlIDwgMi4yZS0xNg0KDQpuYW1lcyhyZXMpDQojIFsxXSAic3RhdGlzdGljIiAicGFyYW1ldGVyIiAicC52YWx1ZSIgIm1ldGhvZCIgImRhdGEubmFtZSINCg0KcmVzJHAudmFsdWUgIyA8IDAuMDUNCiMgQ2hpLXNxdWFyZWQgDQogICAgICAgICAgIyAwIA0KIyBDb25jbHVzaW9uOiBXZSBzaG91bGQgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuDQpgYGANCg0KDQojIyA3IERpY2tleS1GdWxsZXIgVGVzdA0KDQpOdWxsIGh5cG90aGVzaXM6DQpUaGVyZSBpcyBhIHVuaXQgcm9vdC4NCuWNleS9jeagueWtmOWcqA0KDQpgYGB7ciBEaWNrZXktRnVsbGVyIFRlc3R9DQppbnN0YWxsLnBhY2thZ2VzKCJ1cmNhIikNCmxpYnJhcnkodXJjYSkNCmFyZ3ModXIuZGYpDQoNCiMgZnVuY3Rpb24gKHksIHR5cGUgPSBjKCJub25lIiwgImRyaWZ0IiwgInRyZW5kIiksIGxhZ3MgPSAxLCBzZWxlY3RsYWdzID0gYygiRml4ZWQiLCANCiMgICAgICJBSUMiLCAiQklDIikpIA0KIyBOVUxMDQojIHk6IHRpbWUgc2VyaWVzDQojIHk6IOaXtumXtOW6j+WIlw0KIyB0eXBlOiAibm9uZSIsICJkcmlmdCIsIG9yICJ0cmVuZCIgZm9yIHJlZ3Jlc3Npb24gbW9kZWwNCiMgdHlwZTog4oCc5peg4oCd77yM4oCc5ryC56e74oCd77yM5oiW4oCc6LaL5Yq/4oCd5Zue5b2S5qih5Z6LDQojIGxhZ3M6IG51bWJlciBvZiBsYWdzIG9yIG1heCBudW1iZXIgb2YgbGFncyBpZiB1c2luZyBzZWxlY3RsYWdzDQojIGxhZ3M6IOa7nuWQjumHj++8jOaIluWcqOiuvue9rnNlbGVjdGxhZ3Plj4LmlbDlkI7nmoTmnIDlpKfmu57lkI7ph48NCiMgc2VsZWN0bGFnczogImZpeGVkIiwgb3IgZWl0aGVyICJBSUMiIG9yICJCSUMiIGZvciBhdXRvLXNlbGVjdGlvbg0KIyBzZWxlY3RsYWdzOiAiZml4ZWQiLCDmiJbogIXnlKjkuo7oh6rliqjpgInmi6nnmoQiQUlDIuaIliJCSUMiDQoNCiMgRXhhbXBsZToNCmxpYnJhcnkoRmluVFMpDQpkYXRhKGQuc3A5MDAzbGV2KQ0Kc3A1MDAubGV2ZWwgPC0gd2luZG93KGQuc3A5MDAzbGV2LHN0YXJ0PSIxOTk1LTAxLTAxIikNCihodCA8LSB1ci5kZihzcDUwMC5sZXZlbCx0eXBlPSJ0cmVuZCIsbGFncz0yMCxzZWxlY3RsYWdzPSJCSUMiKSkNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMgQXVnbWVudGVkIERpY2tleS1GdWxsZXIgVGVzdCBVbml0IFJvb3QgLyBDb2ludGVncmF0aW9uIFRlc3QgIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMgVGhlIHZhbHVlIG9mIHRoZSB0ZXN0IHN0YXRpc3RpYyBpczogLTEuNDgwNyAxLjYzMSAxLjg5MjUgDQojIOajgOmqjOe7n+iuoemHj+eahOWAvOWIhuWIq+S4uu+8mi0xLjQ4MDcgMS42MzEgMS44OTI1DQoNCmF0dHJpYnV0ZXMoaHQpJHRlc3RzdGF0ICMgdGF1MyA9IC0xLjQ4MDY4NQ0KIyAgICAgICAgICAgICAgICB0YXUzIHBoaTIgcGhpMw0KIyBzdGF0aXN0aWMgLTEuNDgwNjg1IDEuNjMxMDA4IDEuODkyNDk4DQoNCmF0dHJpYnV0ZXMoaHQpJGN2YWwgIyA+IHRhdTMgNXBjdCA9IC0zLjQxDQojICAgICAgIDFwY3QgNXBjdCAxMHBjdA0KIyB0YXUzIC0zLjk2IC0zLjQxIC0zLjEyDQojIHBoaTIgNi4wOSA0LjY4IDQuMDMNCiMgcGhpMyA4LjI3IDYuMjUgNS4zNA0KDQojIENvbmNsdXNpb246IFdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwtaHlwb3RoZXNpcyBvZiBhIHVuaXQgcm9vdA0KIyAodGF1MyBpcyBsZXNzIG5lZ2F0aXZlIHRoYW4gaXRzIGNyaXRpY2FsIHZhbHVlIG9mIC0zLjQxKQ0KIyDnu5PorrrvvJrvvIh0YXUz5rKh5pyJ5Li055WM5YC8LTMuNDHmmL7okZfvvIkNCmBgYA0KDQoNCiMjIDggUGhpbGxpcHMgJiBPdWxpYXJpcyBUZXN0DQoNCk51bGwgaHlwb3RoZXNpczoNCk5vIGNvaW50ZWdyYXRpb24uDQrmsqHmnInljY/mlbTlhbPns7sNCg0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJ1cmNhIikNCmxpYnJhcnkodXJjYSkNCmFyZ3MoY2EucG8pDQoNCiMgZnVuY3Rpb24gKHosIGRlbWVhbiA9IGMoIm5vbmUiLCAiY29uc3RhbnQiLCAidHJlbmQiKSwgbGFnID0gYygic2hvcnQiLCANCiMgICAgICJsb25nIiksIHR5cGUgPSBjKCJQdSIsICJQeiIpLCB0b2wgPSBOVUxMKSANCiMgTlVMTA0KIyB4OiBtYXRyaXggb3IgbXVsdGl2YXJpYXRlIHRpbWUgc2VyaWVzIHRvIGJlIHRlc3RlZA0KIyB4OiDnlKjkuo7mtYvor5XnmoTnn6npmLXmiJblpJrnu7Tml7bpl7Tluo/liJcNCiMgZGVtZWFuOiAibm9uZSIsICJjb25zdGFudCIsIG9yICJ0cmVuZCINCiMgbGFnOiAic2hvcnQiIG9yICJsb25nIiBmb3IgdGhlIGxlbmd0aCBvZiBsYWdzDQojIGxhZzog5rue5ZCO6ZW/5bqm77yMInNob3J0IuaIluiAhSJsb25nIg0KIyB0eXBlOiAiUHUiIG9yICJQeiINCg0KaW5zdGFsbC5wYWNrYWdlcygidHNlcmllcyIpDQpsaWJyYXJ5KHRzZXJpZXMpDQphcmdzKHBvLnRlc3QpDQojIGZ1bmN0aW9uICh4LCBkZW1lYW4gPSBUUlVFLCBsc2hvcnQgPSBUUlVFKSANCiMgTlVMTA0KIyB4OiBtYXRyaXggb3IgbXVsdGl2YXJpYXRlIHRpbWUgc2VyaWVzIHRvIGJlIHRlc3RlZA0KIyBkZW1lYW46IHNob3VsZCBhbiBpbnRlcmNlcHQgYmUgaW5jbHVkZWQgaW4gdGhlIGNvaW50ZWdyYXRpb24NCiMgZGVtZWFuOiDljY/mlbTmmK/lkKbljIXlkKvmiKrot50NCiMgcmVncmVzc2lvbjogKFQvRikNCiMgbHNob3J0OiBUID0gc2hvcnQgbnVtYmVyIG9mIGxhZ3MsIEYgPSBsb25nIG51bWJlciBvZiBsYWdzDQojIGxzaG9ydDogVCA9IOefrea7nuWQjumYtuaVsCwgRiA9IOmVv+a7nuWQjumYtuaVsA0KDQojIEV4YW1wbGU6DQpkYXRhKGVjYikgIyBNYWNyb2Vjb25vbWljIGRhdGEgb2YgdGhlIEV1cm8gWm9uZQ0KIyDmrKflhYPljLrlro/op4Lnu4/mtY7mlbDmja4NCm0zLnJlYWwgPC0gZWNiWywibTMiXS9lY2JbLCJnZHAuZGVmbCJdDQpnZHAucmVhbCA8LSBlY2JbLCJnZHAubm9tIl0vZWNiWywiZ2RwLmRlZmwiXQ0KcmwgPC0gZWNiWywicmwiXQ0KZWNiLmRhdGEgPC0gY2JpbmQobTMucmVhbCwgZ2RwLnJlYWwsIHJsKQ0KDQoobTNkLnBvIDwtIGNhLnBvKGVjYi5kYXRhLCB0eXBlPSJQeiIpKQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIA0KIyBQaGlsbGlwcyBhbmQgT3VsaWFyaXMgVW5pdCBSb290IC8gQ29pbnRlZ3JhdGlvbiBUZXN0ICMgDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgDQojIFRoZSB2YWx1ZSBvZiB0aGUgdGVzdCBzdGF0aXN0aWMgaXM6IDE4LjQ2NTggDQpzbG90TmFtZXMobTNkLnBvKQ0KIyBbMV0gInoiICJ0eXBlIiAibW9kZWwiICJsYWciICJjdmFsIiANCiMgWzZdICJyZXMiICJ0ZXN0c3RhdCIgInRlc3RyZWciICJ0ZXN0Lm5hbWUiDQptM2QucG9AdGVzdHN0YXQNCiMgWzFdIDE4LjQ2NTg0DQptM2QucG9AY3ZhbA0KIyAgICAgICAgICAgICAgICAgICAxMHBjdCA1cGN0IDFwY3QNCiMgY3JpdGljYWwgdmFsdWVzIDYyLjE0MzYgNzEuMjc1MSA4OS42Njc5DQojIENvbmNsdXNpb246IFdlIHNob3VsZCBub3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuDQojIChub3QgYXMgZXh0cmVtZSBhcyBpdHMgY3JpdGljYWwgdmFsdWUpDQojICjkuI3lpoLkuLTnlYzlgLzmmL7okZcpDQoNCihtM2QucG8gPC0gcG8udGVzdChlY2IuZGF0YSkpDQojICAgICAgICAgUGhpbGxpcHMtT3VsaWFyaXMgQ29pbnRlZ3JhdGlvbiBUZXN0DQojIGRhdGE6IGVjYi5kYXRhDQojIFBoaWxsaXBzLU91bGlhcmlzIGRlbWVhbmVkID0gLTQuNDY2NSwgVHJ1bmNhdGlvbiBsYWcNCiMgcGFyYW1ldGVyID0gMCwgcC12YWx1ZSA9IDAuMTUNCg0KbmFtZXMobTNkLnBvKQ0KIyBbMV0gInN0YXRpc3RpYyIgInBhcmFtZXRlciIgInAudmFsdWUiICJtZXRob2QiICJkYXRhLm5hbWUiDQoNCm0zZC5wbyRwLnZhbHVlDQojIFsxXSAwLjE1DQojIENvbmNsdXNpb246IFdlIHNob3VsZCBub3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuDQpgYGANCg0KIyMgOSBKb2hhbnNlbiBQcm9jZWR1cmUgVGVzdA0KDQpOdWxsIGh5cG90aGVzaXM6DQpUaGVyZSBhcmUgbiBjb2ludGVncmF0ZWQgdmVjdG9ycy4NCuaciW7kuKrljY/mlbTlkJHph48NCg0KYGBge3IgSm9oYW5zZW4gUHJvY2VkdXJlIFRlc3R9DQppbnN0YWxsLnBhY2thZ2VzKCJ1cmNhIikNCmxpYnJhcnkodXJjYSkNCmFyZ3MoY2Euam8pDQojIGZ1bmN0aW9uICh4LCB0eXBlID0gYygiZWlnZW4iLCAidHJhY2UiKSwgZWNkZXQgPSBjKCJub25lIiwgImNvbnN0IiwgDQojICAgICAidHJlbmQiKSwgSyA9IDIsIHNwZWMgPSBjKCJsb25ncnVuIiwgInRyYW5zaXRvcnkiKSwgc2Vhc29uID0gTlVMTCwgDQojICAgICBkdW12YXIgPSBOVUxMKSANCiMgTlVMTA0KIyB4OiBkYXRhIG1hdHJpeCB0byBiZSBpbnZlc3RpZ2F0ZWQgZm9yIGNvaW50ZWdyYXRpb24NCiMgeDog55So5LqO5qOA5p+l5Y2P5pW055qE5pWw5o2u55+p6Zi1DQojIHR5cGU6ICJlaWdlbiIgb3IgInRyYWNlIg0KIyBlY2RldDogIm5vbmUiLCAiY29uc3QiLCBvciAidHJlbmQiDQojIEs6IG51bWJlciBvZiBsYWdzDQojIEs6IOa7nuWQjumYtuaVsA0KIyBzcGVjOiBWRUNNIHNwZWNpZmljYXRpb24sICJsb25ncnVuIiBvciAidHJhbnNpdG9yeSINCiMgc3BlYzogVkVDTeinhOiMg++8miJsb25ncnVuIuaIliJ0cmFuc2l0b3J5Ig0KDQojIEV4YW1wbGU6DQpkYXRhKGRlbm1hcmspDQpzamQgPC0gZGVubWFya1ssIGMoIkxSTSIsICJMUlkiLCAiSUJPIiwgIklERSIpXQ0KKHNqZC52ZWNtIDwtIGNhLmpvKHNqZCwgZWNkZXQgPSAiY29uc3QiLCB0eXBlPSJlaWdlbiIsIEs9MiwNCisgc3BlYz0ibG9uZ3J1biIsc2Vhc29uPTQpKQ0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgDQojIEpvaGFuc2VuLVByb2NlZHVyZSBVbml0IFJvb3QgLyBDb2ludGVncmF0aW9uIFRlc3QgIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMgVGhlIHZhbHVlIG9mIHRoZSB0ZXN0IHN0YXRpc3RpYyBpczogMi4zNTIyIDYuMzQyNyAxMC4zNjIgMzAuMDg3NSANCnN1bW1hcnkoc2pkLnZlY20pDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIA0KIyBKb2hhbnNlbi1Qcm9jZWR1cmUgIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgDQojIFRlc3QgdHlwZTogbWF4aW1hbCBlaWdlbnZhbHVlIHN0YXRpc3RpYyAobGFtYmRhIG1heCkgLCB3aXRob3V0IGxpbmVhciB0cmVuZCBhbmQgY29uc3RhbnQgaW4gY29pbnRlZ3JhdGlvbiANCiMg5rWL6K+V57G75Z6L77ya5rKh5pyJ57q/5oCn6LaL5Yq/5bm25Y2P5pW05oGS5a6a55qE5pyA5aSn54m55b6B5YC857uf6K6h77yIzrvmnIDlpKfvvIkNCiMgRWlnZW52YWx1ZXMgKGxhbWJkYSk6DQojIOeJueW+geWAvO+8iM6777yJ77yaDQojIFsxXSA0LjMzMTY1NGUtMDEgMS43NzU4MzZlLTAxIDEuMTI3OTA1ZS0wMSA0LjM0MTEzMGUtMDINCiMgWzVdIC04Ljk0NzIzNmUtMTYNCiMgVmFsdWVzIG9mIHRlc3RzdGF0aXN0aWMgYW5kIGNyaXRpY2FsIHZhbHVlcyBvZiB0ZXN0Og0KIyDmtYvor5Xmo4Dpqoznu5/orqHph4/nmoTlgLzlkozkuLTnlYzlgLzvvJoNCiMgICAgICAgICAgIHRlc3QgMTBwY3QgNXBjdCAxcGN0DQojIHIgPD0gMyB8IDIuMzUgNy41MiA5LjI0IDEyLjk3DQojIHIgPD0gMiB8IDYuMzQgMTMuNzUgMTUuNjcgMjAuMjANCiMgciA8PSAxIHwgMTAuMzYgMTkuNzcgMjIuMDAgMjYuODENCiMgciA9IDAgfCAzMC4wOSAyNS41NiAyOC4xNCAzMy4yNA0KIyBFaWdlbnZlY3RvcnMsIG5vcm1hbGlzZWQgdG8gZmlyc3QgY29sdW1uOg0KIyDlvZLkuIDljJbnmoTnibnlvoHlkJHph48NCiMgKFRoZXNlIGFyZSB0aGUgY29pbnRlZ3JhdGlvbiByZWxhdGlvbnMpDQojIOayoeacieWNj+aVtOWFs+ezuw0KIyAgICAgICAgICAgICBMUk0ubDIgTFJZLmwyIElCTy5sMiBJREUubDIgY29uc3RhbnQNCiMgTFJNLmwyIDEuMDAwMDAwIDEuMDAwMDAwMCAxLjAwMDAwMDAgMS4wMDAwMDAgMS4wMDAwMDAwDQojIExSWS5sMiAtMS4wMzI5NDkgLTEuMzY4MTAzMSAtMy4yMjY2NTgwIC0xLjg4MzYyNSAtMC42MzM2OTQ2DQojIElCTy5sMiA1LjIwNjkxOSAwLjI0Mjk4MjUgMC41MzgyODQ3IDI0LjM5OTQ4NyAxLjY5NjU4MjgNCiMgSURFLmwyIC00LjIxNTg3OSA2Ljg0MTExMDMgLTUuNjQ3MzkwMyAtMTQuMjk4MDM3IC0xLjg5NTE1ODkNCiMgY29uc3RhbnQgLTYuMDU5OTMyIC00LjI3MDg0NzQgNy44OTYzNjk2IC0yLjI2MzIyNCAtOC4wMzMwMTI3DQojIFdlaWdodHMgVzoNCiMgKFRoaXMgaXMgdGhlIGxvYWRpbmcgbWF0cml4KQ0KIyDvvIjov5nmmK/ovb3ojbfnn6npmLXvvIkNCiMgICAgICAgICAgICBMUk0ubDIgTFJZLmwyIElCTy5sMiBJREUubDINCiMgTFJNLmQgLTAuMjEyOTU0OTQgLTAuMDA0ODE0OTggMC4wMzUwMTExMjggMi4wMjg5MDhlLTAzDQojIExSWS5kIDAuMTE1MDIyMDQgMC4wMTk3NTAyOCAwLjA0OTkzODQ2MCAxLjEwODY1NGUtMDMNCiMgSUJPLmQgMC4wMjMxNzcyNCAtMC4wMTA1OTYwNSAwLjAwMzQ4MDM1NyAtMS41NzM3NDJlLTAzDQojIElERS5kIDAuMDI5NDExMDkgLTAuMDMwMjI5MTcgLTAuMDAyODExNTA2IC00Ljc2NzYyN2UtMDUNCiMgICAgICAgICAgICBjb25zdGFudA0KIyBMUk0uZCAtNC4xODMzNjNlLTEzDQojIExSWS5kIDQuNjE4MTM1ZS0xMw0KIyBJQk8uZCAzLjY3MzEzNmUtMTQNCiMgSURFLmQgLTEuMTE1MDg3ZS0xNA0KDQpzbG90TmFtZXMoc2pkLnZlY20pDQojICBbMV0gIngiICJaMCIgIloxIiAiWksiICJ0eXBlIiANCiMgIFs2XSAibW9kZWwiICJlY2RldCIgImxhZyIgIlAiICJzZWFzb24iIA0KIyBbMTFdICJkdW12YXIiICJjdmFsIiAidGVzdHN0YXQiICJsYW1iZGEiICJWb3JnIiANCiMgWzE2XSAiViIgIlciICJQSSIgIkRFTFRBIiAiR0FNTUEiIA0KIyBbMjFdICJSMCIgIlJLIiAiYnAiICJzcGVjIiAiY2FsbCIgDQojIFsyNl0gInRlc3QubmFtZSINCnNqZC52ZWNtQHRlc3RzdGF0DQojIFsxXSAyLjM1MjIzMyA2LjM0MjczMCAxMC4zNjE5NTAgMzAuMDg3NDUxDQpzamQudmVjbUBjdmFsICMgMTAuMzYgPCByPD0xID0gMjIuMDAgDQojICAgICAgICAgIDEwcGN0IDVwY3QgMXBjdA0KIyByIDw9IDMgfCA3LjUyIDkuMjQgMTIuOTcNCiMgciA8PSAyIHwgMTMuNzUgMTUuNjcgMjAuMjANCiMgciA8PSAxIHwgMTkuNzcgMjIuMDAgMjYuODENCiMgciA9IDAgfCAyNS41NiAyOC4xNCAzMy4yNA0KIyBDb25jbHVzaW9uOiBUaGVyZSBhcmUgMSBjb2ludGVncmF0ZWQgdmVjdG9yLg0KIyDnu5PorrrvvJrmnIkx5Liq5Y2P5pW05ZCR6YeP44CCDQpgYGANCg0KIyMgMTAgS+ajgOmqjCjnu4/pqozliIbluIPnmoRLb2xtb2dvcm92LVNtaXJub3bmo4DpqowpDQoNClLlh73mlbA6a3MudGVzdCgpDQoNCuWmguaenFDlgLzlvojlsI/vvIzor7TmmI7mi5Lnu53ljp/lgYforr7vvIzooajmmI7mlbDmja7kuI3nrKblkIhGKG4sbSnliIbluIPjgIINCg0KDQojIyAxMSBULXRlc3QgVOajgOmqjA0KDQrnlKjkuo7mraPmgIHmgLvkvZPlnYflgLzlgYforr7mo4DpqozvvIzljZXmoLfmnKzvvIzlj4zmoLfmnKzpg73lj6/ku6XjgILlj6/ku6Xlj4zovrnmo4DpqozvvIzkuZ/lj6/ku6XljZXovrnmo4DpqozjgIINCg0K5a+55LqO5Y2V5qC35pys77yM5LiO57uZ5a6a55qE5Z2H5YC85YGa5q+U6L6D77yaDQrvvIgx77yJ5Y+M6L655qOA6aqM77yM5Lmf5bCx5pivDQpOdWxsIGh5cG90aGVzaXM6DQrov5nkuKrmoLfmnKznmoTlnYflgLzkuI7nu5nlrprlnYflgLznm7jnrYnvvJpIMO+8miB1ID0gdTANCg0KQWx0ZXJuYXRpdmUgaHlwb3RoZXNpczoNCui/meS4quagt+acrOeahOWdh+WAvOS4jue7meWumuWdh+WAvOS4jeebuOetie+8mkgx77yaIHUg4omgIHUwDQoNCu+8iDLvvInljZXovrnmo4DpqozvvIzkuZ/lsLHmmK8NCuWNlei+ueajgOmqjEkNCk51bGwgaHlwb3RoZXNpczoNCui/meS4quagt+acrOeahOWdh+WAvOWwj+S6jue7meWumuWdh+WAvO+8mkgw77yaIHUg4omkIHUwDQoNCkFsdGVybmF0aXZlIGh5cG90aGVzaXM6DQrov5nkuKrmoLfmnKznmoTlnYflgLzlpKfkuo7nu5nlrprlnYflgLzvvJpIMe+8miB1IO+8niB1MA0KDQrljZXovrnmo4DpqoxJSe+8iOWNlei+ueajgOmqjEnlj43ov4fmnaXvvIkNCk51bGwgaHlwb3RoZXNpczoNCui/meS4quagt+acrOeahOWdh+WAvOWkp+S6juetieS6jue7meWumuWdh+WAvO+8mkgw77yaIHUg4omlIHUwDQoNCkFsdGVybmF0aXZlIGh5cG90aGVzaXM6DQrov5nkuKrmoLfmnKznmoTlnYflgLzlsI/kuo7nu5nlrprlnYflgLzvvJpIMe+8miB1IO+8nCB1MA0KDQrlr7nkuo7lj4zmoLfmnKzvvIzlsLHmmK/kuKTkuKrmoLfmnKznmoTlnYflgLzlgZrmr5TovoPjgILljZXovrnjgIHlj4zovrnmo4DpqozkuI7ljZXmoLfmnKzkuIDmoLfjgIINCg0K57uT5p6c5oSP5LmJ77yaUOWAvOWwj+S6juaYvuiRl+aAp+awtOW5s+aXtuaLkue7neWOn+WBh+iuvu+8jOWQpuWIme+8jOaOpeWPl+WOn+WBh+iuvuOAguWFt+S9k+eahOWBh+iuvuimgeeci+aJgOmAieaLqeeahOaYr+WPjOi+ueWBh+iuvui/mOaYr+WNlei+ueWBh+iuvu+8iOWPiOWIhuWwj+S6juWSjOWkp+S6ju+8iQ0KDQpgYGB7ciB0LnRlc3QxfQ0KdC50ZXN0KHgsIHkgPSBOVUxMLA0KYWx0ZXJuYXRpdmUgPSBjKCJ0d28uc2lkZWQiLCAibGVzcyIsICJncmVhdGVyIiksDQptdSA9IDAsIHBhaXJlZCA9IEZBTFNFLCB2YXIuZXF1YWwgPSBGQUxTRSwNCmNvbmYubGV2ZWwgPSAwLjk1LCAuLi4pDQpgYGANCg0KIyMgMTIg5q2j5oCB5oC75L2T5pa55beu5qOA6aqMDQoNCueUqOS6juato+aAgeaAu+S9k+aWueW3ruWBh+iuvuajgOmqjO+8jOWNleagt+acrO+8jOWPjOagt+acrOmDveWPr+S7peOAguWPr+S7peWPjOi+ueajgOmqjO+8jOS5n+WPr+S7peWNlei+ueajgOmqjOOAguS4juWdh+WAvOWBh+iuvuajgOmqjOexu+S8vO+8jOS4jei/h+ajgOmqjOeahOWvueixoeWPmOaIkOaWueW3ruS6huOAgg0KDQrnu5PmnpzlkKvkuYnvvJpQ5YC85bCP5LqO5pi+6JGX5oCn5rC05bmz5pe25ouS57ud5Y6f5YGH6K6+77yM5ZCm5YiZ77yM5o6l5Y+X5Y6f5YGH6K6+44CC5YW35L2T55qE5YGH6K6+6KaB55yL5omA6YCJ5oup55qE5piv5Y+M6L655YGH6K6+6L+Y5piv5Y2V6L655YGH6K6+77yI5Y+I5YiG5bCP5LqO5ZKM5aSn5LqO77yJDQoNCmBgYHtyIHQudGVzdDJ9DQp0LnRlc3QoeCwgeSA9IE5VTEwsDQphbHRlcm5hdGl2ZSA9IGMoInR3by5zaWRlZCIsICJsZXNzIiwgImdyZWF0ZXIiKSwNCm11ID0gMCwgcGFpcmVkID0gRkFMU0UsIHZhci5lcXVhbCA9IEZBTFNFLA0KY29uZi5sZXZlbCA9IDAuOTUsIC4uLikNCmBgYA0KDQojIyAxMyDkuozpobnliIbluIPmgLvkvZPlgYforr7mo4DpqowNCmBgYHtyIGJpbm9tLnRlc3R9DQpiaW5vbS50ZXN0KHgsIG4sIHAgPSAwLjUsDQphbHRlcm5hdGl2ZSA9IGMoInR3by5zaWRlZCIsICJsZXNzIiwgImdyZWF0ZXIiKSwNCmNvbmYubGV2ZWwgPSAwLjk1KQ0KYGBgDQoNCiMjIDE0IFBlYXJzb24g5ouf5ZCI5LyY5bqmz4cy5qOA6aqMDQoNCuWOn+WBh+iuvkgw77yaWOespuWQiEbliIbluIPjgIINCnAt5YC85bCP5LqO5p+Q5Liq5pi+6JGX5oCn5rC05bmz77yM5YiZ6KGo56S65ouS57ud5Y6f5YGH6K6+77yM5ZCm5YiZ5o6l5Y+X5Y6f5YGH6K6+44CCDQpgYGB7ciBjaGlzcS50ZXN0fQ0KY2hpc3EudGVzdCh4LCB5ID0gTlVMTCwgY29ycmVjdCA9IFRSVUUsDQpwID0gcmVwKDEvbGVuZ3RoKHgpLCBsZW5ndGgoeCkpLCByZXNjYWxlLnAgPSBGQUxTRSwNCnNpbXVsYXRlLnAudmFsdWUgPSBGQUxTRSwgQiA9IDIwMDApDQpgYGANCg0KIyMgMTUgRmlzaGVy57K+56Gu55qE54us56uL5qOA6aqM77yaDQrljp/lgYforr7vvJpYLFnnm7jlhbMNCg0KYGBge3IgZmlzaGVyLnRlc3R9DQpmaXNoZXIudGVzdCh4LCB5ID0gTlVMTCwgd29ya3NwYWNlID0gMjAwMDAwLCBoeWJyaWQgPSBGQUxTRSwNCmNvbnRyb2wgPSBsaXN0KCksIG9yID0gMSwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIiwNCmNvbmYuaW50ID0gVFJVRSwgY29uZi5sZXZlbCA9IDAuOTUpDQpgYGANCg0KIyMgMTYgTWNOZW1hcuajgOmqjO+8mg0K5Y6f5YGH6K6+77ya5Lik57uE5pWw5o2u55qE6aKR5pWw5rKh5pyJ5Yy65Yir44CCDQpgYGB7ciBtY25lbWFyLnRlc3R9DQptY25lbWFyLnRlc3QoeCwgeSA9IE5VTEwsIGNvcnJlY3QgPSBUUlVFKQ0KYGBgDQoNCiMjIDE3IOenqeebuOWFs+ajgOmqjA0KDQrljp/lgYforr7vvJp4LHnnm7jlhbMuDQpgYGB7ciBzcGVhcm1hbiBjb3IudGVzdH0NCmNvci50ZXN0KHgsIHksDQphbHRlcm5hdGl2ZSA9IGMoInR3by5zaWRlZCIsICJsZXNzIiwgImdyZWF0ZXIiKSwNCm1ldGhvZCA9ICJzcGVhcm1hbiIsIGNvbmYubGV2ZWwgPSAwLjk1LCAuLi4pDQpgYGANCg0KIyMgMTggV2lsY294b27np6nmo4DpqowNCg0K5Y6f5YGH6K6+77ya5Lit5L2N5pWw5aSn5LqO77yM5bCP5LqO77yM5LiN562J5LqObXUuDQpgYGB7ciB3aWxjb3gudGVzdH0NCndpbGNveC50ZXN0KHgsIHkgPSBOVUxMLA0KYWx0ZXJuYXRpdmUgPSBjKCJ0d28uc2lkZWQiLCAibGVzcyIsICJncmVhdGVyIiksDQptdSA9IDAsIHBhaXJlZCA9IEZBTFNFLCBleGFjdCA9IE5VTEwsIGNvcnJlY3QgPSBUUlVFLA0KY29uZi5pbnQgPSBGQUxTRSwgY29uZi5sZXZlbCA9IDAuOTUsIC4uLikNCmBgYA0KDQoNCg0KDQogICAgICAgICAg